#include "CodeHelper.h"

#include "QDebug"
#include "QDir"
#include "QFile"

#include "iostream"

#include"UI/MainWindow.h"

#include "QTextStream"
#include<QObject>
#include<Util/handlefile.h>
CodeHelper::CodeHelper()
{

}

//初始化数据
void CodeHelper::init(QWidget *Widget, QString javaHome, QString packageName, QString dirPath)
{
    this->widget=Widget;
    this->_javaHome = "\""+javaHome+"\"";
    this->_packageName = packageName;
    this->DirPath=dirPath;
}



//======================Main.java============================

//包名：$packagename

//引用：$importer

//将模型容器发来的udx转换为模型可以运行的数据：$parseudxdata

//模型计算：$calculate

//计算结果处理：$result2udx

bool CodeHelper::readMainCode(EInputDataType dataType)
{
   // qDebug()<<"current path:"<<QDir::currentPath();
    qDebug()<<"path"<<DirPath;
    QFile file(DirPath+"\\templates\\templateFiles\\Slope\\Main.java");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        std::cout<<"failed to open template.\n";
        return false;
    }

    QString str(file.readAll());

    file.close();

    //包名
    if(!this->_packageName.isNull())
    str.replace("$packagename",this->_packageName);
    else {
        qWarning()<<"Please Input packageName."<<endl;
        return false;
    }

    //引用
    if(dataType == EInputDataType::ASCIIGRID)
    {
        str.replace("$importer","import com.udx.helper.AsciiGridUdxHelper;");


        QString parserStr ;

        //将模型容器传过来的udx数据解析出来到一个临时目录
        parserStr.append("String asciiGridStr = AsciiGridUdxHelper.udx2AsciiGrid(udxDataset);\n");
        parserStr.append("      String saveTmpDir = PathUtil.getPath(Main.class) + \"\\tmpData\";\n");
        parserStr.append("      File file = new File(saveTmpDir);\n");
        parserStr.append("      if(!file.exists() && !file.isDirectory()){\n");
        parserStr.append("            file.mkdir();\n");
        parserStr.append("        }\n");
        parserStr.append("\n");
        parserStr.append("        String saveTmpPath = saveTmpDir + \"\\\\srcDem.txt\";\n");
        parserStr.append("        file = new File(saveTmpPath);\n");
        parserStr.append("        if(file.exists()){\n");
        parserStr.append("            file.delete();\n");
        parserStr.append("        }\n");
        parserStr.append("\n");
        parserStr.append("        try {\n");
        parserStr.append("            FileOutputStream fos = new FileOutputStream(file);\n");
        parserStr.append("\n");
        parserStr.append("            fos.write(asciiGridStr.getBytes());\n");
        parserStr.append("            fos.flush();\n");
        parserStr.append("            fos.close();\n");
        parserStr.append("\n");
        parserStr.append("        } catch (Exception e) {\n");
        parserStr.append("            System.out.println(\"write temp AsciiGrid data failed...\");\n");
        parserStr.append("            e.printStackTrace();\n");
        parserStr.append("        }\n");

        str.replace("$parseudxdata",parserStr);


        parserStr.clear();

        //开始计算
        parserStr.append("String resultPath = saveTmpDir+\"\\\\outAsciiGrid.txt\";\n");
        parserStr.append("int res = modelHandle.SlopeAnalysis(saveTmpPath,resultPath,1);\n");

        str.replace("$calculate",parserStr);


        parserStr.clear();
        //转换计算结果数据

        parserStr.append("udx_return_Dt = AsciiGridUdxHelper.asciiGrid2Udx(resultPath, resultPath);\n");

        str.replace("$result2udx",parserStr);

        parserStr.clear();

    }else{
        //其他的数据格式帮助类
    }

    //保存文件
    if(!str.isNull()&&this->saveFile(DirPath+"\\java\\Main.java",str)){
        return true;
    }
    else {
        return false;
        qWarning()<<"Code generation error."<<endl;
    }
    return true;
}



//=====================ModelPackHandle.java===================

//包名：$packagename

//JNI加载外部库： $jniload

//模型计算入口：$modelcalc

bool CodeHelper::readModelHandleCode()
{
    QFile file(DirPath+"\\templates\\templateFiles\\Slope\\ModelHandle.java");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        qWarning()<<"failed to open template.\n"<<endl;
        return false;
    }

    QString str(file.readAll());

    file.close();

    //包名
    str.replace("$packagename",this->_packageName);

    QString parseStr;
    //jni导入dll
//    for(int index=0;index<libNamesList->count();index++){
//        qDebug()<<"dllName:"<<libNamesList->value(index);
//    }

    ///////////////////测试用，这里先写死，不传入用户添加的dll文件//////////////////////
    parseStr.append("System.load(PathUtil.getPath(Main.class) + \"\\\\pthreadVC2.dll\");\n");
    parseStr.append("System.load(PathUtil.getPath(Main.class) + \"\\\\StringFunc.dll\");\n");
    parseStr.append("System.load(PathUtil.getPath(Main.class) + \"\\\\tinyxml2.dll\");\n");
    parseStr.append("System.load(PathUtil.getPath(Main.class) + \"\\\\ModelPacking.dll\");\n");

    str.replace("$jniload",parseStr);

    parseStr.clear();

    //模型计算入口
    parseStr.append("public native int SlopeAnalysis(String sourceFileName,String resultFileName, int method);");

    str.replace("$modelcalc",parseStr);

    parseStr.clear();

    if(!str.isNull() && this->saveFile(DirPath+"\\java\\ModelHandle.java",str)){
        return true;
    }else{
        qWarning()<<"ModelHandle.java fix error."<<endl;
        return false;
    }

}

//入口函数： $mainmethod

//依赖jar包：$jars

bool CodeHelper::readMainfest()
{
    QFile file(DirPath+"\\templates\\templateFiles\\Slope\\MANIFEST.MF");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        qDebug()<<"failed to read mainfest.mf file.\n";
        return false;
    }

    QString str(file.readAll());

    file.close();

    str.replace("$mainmethod","com.ngis.slope.Main");

    str.replace("$jars","./libs/udxhelper.jar ./libs/udx.jar ./libs/util.jar ./libs/runcontext.jar");

     if(!str.isNull()&&this->saveFile(DirPath+"\\java\\MANIFEST.MF",str)){
         return true;
     }else{
         qWarning()<<"Mainfest.MF fix error."<<endl;
         return false;
     }

}

bool CodeHelper::readCompileBatFile()
{
    QFile file(DirPath+"\\templates\\templateFiles\\Slope\\compile.bat");
    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        qWarning()<<"failed to read mainfest.mf file.\n"<<endl;
        return false;
    }
    QString str(file.readAll());
    file.close();
    QString str1=this->DirPath;
    str.replace("${dirPath}",str1.replace("/","\\"));
    str.replace("${JAVAHOME}",_javaHome);
    if(!str.isNull()&&this->saveFile(DirPath+"\\java\\compile.bat",str)){
        return true;
    }else{
        qWarning()<<"compile.bat fix error."<<endl;
        return false;
    }
}

bool CodeHelper::getLicense(QString AreaText){
    if(!AreaText.isNull()&&this->saveFile(DirPath+"/wrapper/license.txt",AreaText)){
        return true;
    }else{
        qWarning()<<"compile.bat fix error."<<endl;
        return false;
    }
    return true;

}

bool CodeHelper::otherCompile(){
    char*  ch;
    QByteArray ba = (DirPath+"\\java\\compile.bat").toLatin1();
    if(ba.isNull()) return false;
    ch=ba.data();
    system(ch);
    qDebug() << "code compile sucess." <<endl;
    return true;
}

int CodeHelper::otherPackaged(){
    QString fileName = QFileDialog::getSaveFileName(widget,
            QObject::tr("Save zip"),
            "",
            QObject::tr("Zip Files (*.zip)"));


            QString winRARPath = "\""+this->DirPath+"\\templates\\winrar\\WinRAR.exe"+"\"";
            QString ZipPath = "\""+fileName+"\"";
            QString SrcFoldPath = "\""+this->DirPath+"\\wrapper\\"+"\"";
            QString commandStr = (winRARPath+" a -ep1 -r -m3 -ibck "+ZipPath+" "+SrcFoldPath);

            QProcess p(0);
            p.start(commandStr);
            p.waitForStarted();
            p.waitForFinished();
            qWarning()<<QString::fromLocal8Bit(p.readAllStandardError())<<endl;

            //删除临时文件，临时文件夹
            if(DelDir(DirPath+"/JavaTemp")&& DelDir(DirPath+"/java")&& DelDir(DirPath+"/wrapper")){
                qWarning()<<"Delete the fold successfully."<<endl;
                return 1;
            }else{
                qWarning()<<"Failed to delete the fold."<<endl;
                 return 0;
            }



}

void CodeHelper::setJavaHome(QString javaHome)
{
        this->_javaHome = javaHome;
}

QString &CodeHelper::getJavaHome()
{

    return this->_javaHome;
}

bool CodeHelper::saveFile(QString filename,QString& str)
{
    QFile file(filename);

    if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
    {
        std::cout<<"error : failed to save file.\n";
        return false;
    }

    QTextStream in(&file);
    in << str;

    in.flush();
    file.close();
    return true;
}
